/*
 * @Autor: Ruohong Yu
 * @Date: 2023-04-01 15:14:48
 * @Description: file content
 * @FilePath: \ebookd:\program\vsc\ebook\node-ebook\router_handler\book.js
 */
const { cache } = require('@hapi/joi/lib/base')
const constant = require('../bin/const')
const conn = constant.db

function randomArray(n,l){
  let rnd=[]
  for(let i=0;i<n;i++){
    rnd.push(Math.floor(Math.random()*l))
  }
  return rnd
}
function Random(min, max) {
  return Math.round(Math.random() * (max - min)) + min;
}

function createGuessYouLike(data){
  const n=parseInt(randomArray(1,3))+1
  data['type']=n
  switch(n){
    case 1:
      data['result']=data.id%2===0?'《Executing Magic》':'《Elements of Robotics》'
      break
    case 2:
      data['result']=data.id%2===0?'《Improving Psychiatric Care》':'《Programming Languages》'
      break
    case 3:
      data['result']='《Living with Disfigurement》'
      data['percent']=data.id%2===0?'92%':'97%'
      break
  }
  return data
}

function getGuessYouLike(data,userbooklist){
  const n=parseInt(randomArray(1,3))+1
  data['type']=n
  switch(n){
    case 1:
      data['result']='《'+userbooklist[0]+'》'
      break
    case 2:
      data['result']='《'+userbooklist[1]+'》'
      break
    case 3:
      data['result']='《'+userbooklist[2]+'》'
      data['percent']=data.id%2===0?'92%':'97%'
      break
  }
  return data
}

function createData(results,key){
  return handleData(results[key])
}

function handleData(data){
  if(!data.cover.startsWith('http://')){
    data['cover']=`${constant.resUrl}/img${data.cover}`
  }
  data['selected']=false
  data['private']=false
  data['cache']=false
  data['haveRead']=0
  return data
}

function createCategoryIds(n){
  const arr=[]
  constant.category.forEach((item,index)=>{
    arr.push(index+1)
  })
  const result=[]
  for(let i=0;i<n;i++){
    const ran=Math.floor(Math.random()*arr.length-i)
    result.push(arr[ran])
    arr[ran]=arr[arr.length-i-1]
  }
  return result
}

function createCategoryData(data){
  const categoryIds=createCategoryIds(6)
  const result=[]
  categoryIds.forEach(categoryId=>{
    const subList=data.filter(item=>item.category===categoryId).slice(0,4)
    subList.map(item=>{
      return handleData(item)
    })
    result.push({
      category:categoryId,
      list:subList
    })
  })
  return result.filter(item=>item.list.length===4)
}

function getAllBookReader(data){
  return new Promise((resolve,reject)=>{
    conn.query('select * from user_read where bookname=?',data.fileName,(err,results)=>{
      if(err) return {status:1,message:err}
      data['readers']=results.length
      resolve(data)
    })
  })
}

function getThrReader(readbook){
  return new Promise((resolve,reject)=>{
    var max = 0;
    var secmax = 0;
    var sub = 0;
    var secsub = 1;
    var thmax = 0;
    var thsub = 2;
    for(var i=0;i<readbook.length;i++){
      if (readbook[i].readers > max) {
        max = readbook[i].readers;
        sub = i;
      } else if (readbook[i].readers > secmax) {
        secmax = readbook[i].readers;
        secsub = i;
      } else if (readbook[i].readers > thmax){
        thmax = readbook[i].readers;
        thsub = i;
      }
    }
    resolve({firsub:sub,secsub:secsub,thrsub:thsub})
  })
}

function getUserReadList(username){
  return new Promise((resolve,reject)=>{
    conn.query('select bookname from user_read where username=?',username,(err,results)=>{
      if(err) return {status:1,message:err}
      resolve(results)
    })
  })
}
function getUserList(){
  return new Promise((resolve,reject)=>{
    conn.query('select username from users',(err,results)=>{
      if(err) return {status:1,message:err}
      resolve(results)
    })
  })
}

function getBookInfo(bookname){
  return new Promise((resolve,reject)=>{
    conn.query('select * from book where fileName=?',bookname,(err,results)=>{
      if(err) return {status:1,message:err}
      resolve(results)
    })
  })
}


exports.getHomeDetail=(req,res)=>{
  conn.query('select * from book where cover!=\'\'',async (err,results)=>{
    const length=results.length
    const guessYouLike=[]
    const userReadList=[]
    let userList=[]
    let similarityMatrix=[]
    const banner=constant.resUrl+'/home_banner.jpg'
    const recommend=[]
    const readbook=[]
    const featured=[]
    const random=[]
    const categoryList=createCategoryData(results)
    const categories=[
      {
        category: 1,
        num: 56,
        img1: constant.resUrl + '/cover/cs/A978-3-319-62533-1_CoverFigure.jpg',
        img2: constant.resUrl + '/cover/cs/A978-3-319-89366-2_CoverFigure.jpg'
      },
      {
        category: 2,
        num: 51,
        img1: constant.resUrl + '/cover/ss/A978-3-319-61291-1_CoverFigure.jpg',
        img2: constant.resUrl + '/cover/ss/A978-3-319-69299-9_CoverFigure.jpg'
      },
      {
        category: 3,
        num: 32,
        img1: constant.resUrl + '/cover/eco/A978-3-319-69772-7_CoverFigure.jpg',
        img2: constant.resUrl + '/cover/eco/A978-3-319-76222-7_CoverFigure.jpg'
      },
      {
        category: 4,
        num: 60,
        img1: constant.resUrl + '/cover/edu/A978-981-13-0194-0_CoverFigure.jpg',
        img2: constant.resUrl + '/cover/edu/978-3-319-72170-5_CoverFigure.jpg'
      },
      {
        category: 5,
        num: 23,
        img1: constant.resUrl + '/cover/eng/A978-3-319-39889-1_CoverFigure.jpg',
        img2: constant.resUrl + '/cover/eng/A978-3-319-00026-8_CoverFigure.jpg'
      },
      {
        category: 6,
        num: 42,
        img1: constant.resUrl + '/cover/env/A978-3-319-12039-3_CoverFigure.jpg',
        img2: constant.resUrl + '/cover/env/A978-4-431-54340-4_CoverFigure.jpg'
      },
      {
        category: 7,
        num: 7,
        img1: constant.resUrl + '/cover/geo/A978-3-319-56091-5_CoverFigure.jpg',
        img2: constant.resUrl + '/cover/geo/978-3-319-75593-9_CoverFigure.jpg'
      },
      {
        category: 8,
        num: 18,
        img1: constant.resUrl + '/cover/his/978-3-319-65244-3_CoverFigure.jpg',
        img2: constant.resUrl + '/cover/his/978-3-319-92964-4_CoverFigure.jpg'
      },
      {
        category: 9,
        num: 13,
        img1: constant.resUrl + '/cover/law/2015_Book_ProtectingTheRightsOfPeopleWit.jpeg',
        img2: constant.resUrl + '/cover/law/2016_Book_ReconsideringConstitutionalFor.jpeg'
      },
      {
        category: 10,
        num: 24,
        img1: constant.resUrl + '/cover/ls/A978-3-319-27288-7_CoverFigure.jpg',
        img2: constant.resUrl + '/cover/ls/A978-1-4939-3743-1_CoverFigure.jpg'
      },
      {
        category: 11,
        num: 6,
        img1: constant.resUrl + '/cover/lit/2015_humanities.jpg',
        img2: constant.resUrl + '/cover/lit/A978-3-319-44388-1_CoverFigure_HTML.jpg'
      },
      {
        category: 12,
        num: 14,
        img1: constant.resUrl + '/cover/bio/2016_Book_ATimeForMetabolismAndHormones.jpeg',
        img2: constant.resUrl + '/cover/bio/2017_Book_SnowSportsTraumaAndSafety.jpeg'
      },
      {
        category: 13,
        num: 16,
        img1: constant.resUrl + '/cover/bm/2017_Book_FashionFigures.jpeg',
        img2: constant.resUrl + '/cover/bm/2018_Book_HeterogeneityHighPerformanceCo.jpeg'
      },
      {
        category: 14,
        num: 16,
        img1: constant.resUrl + '/cover/es/2017_Book_AdvancingCultureOfLivingWithLa.jpeg',
        img2: constant.resUrl + '/cover/es/2017_Book_ChinaSGasDevelopmentStrategies.jpeg'
      },
      {
        category: 15,
        num: 2,
        img1: constant.resUrl + '/cover/ms/2018_Book_ProceedingsOfTheScientific-Pra.jpeg',
        img2: constant.resUrl + '/cover/ms/2018_Book_ProceedingsOfTheScientific-Pra.jpeg'
      },
      {
        category: 16,
        num: 9,
        img1: constant.resUrl + '/cover/mat/2016_Book_AdvancesInDiscreteDifferential.jpeg',
        img2: constant.resUrl + '/cover/mat/2016_Book_ComputingCharacterizationsOfDr.jpeg'
      },
      {
        category: 17,
        num: 20,
        img1: constant.resUrl + '/cover/map/2013_Book_TheSouthTexasHealthStatusRevie.jpeg',
        img2: constant.resUrl + '/cover/map/2016_Book_SecondaryAnalysisOfElectronicH.jpeg'
      },
      {
        category: 18,
        num: 16,
        img1: constant.resUrl + '/cover/phi/2015_Book_TheOnlifeManifesto.jpeg',
        img2: constant.resUrl + '/cover/phi/2017_Book_Anti-VivisectionAndTheProfessi.jpeg'
      },
      {
        category: 19,
        num: 10,
        img1: constant.resUrl + '/cover/phy/2016_Book_OpticsInOurTime.jpeg',
        img2: constant.resUrl + '/cover/phy/2017_Book_InterferometryAndSynthesisInRa.jpeg'
      },
      {
        category: 20,
        num: 26,
        img1: constant.resUrl + '/cover/psa/2016_Book_EnvironmentalGovernanceInLatin.jpeg',
        img2: constant.resUrl + '/cover/psa/2017_Book_RisingPowersAndPeacebuilding.jpeg'
      },
      {
        category: 21,
        num: 3,
        img1: constant.resUrl + '/cover/psy/2015_Book_PromotingSocialDialogueInEurop.jpeg',
        img2: constant.resUrl + '/cover/psy/2015_Book_RethinkingInterdisciplinarityA.jpeg'
      },
      {
        category: 22,
        num: 1,
        img1: constant.resUrl + '/cover/sta/2013_Book_ShipAndOffshoreStructureDesign.jpeg',
        img2: constant.resUrl + '/cover/sta/2013_Book_ShipAndOffshoreStructureDesign.jpeg'
      }
    ]
    
    await getUserList().then((res)=>{
      userList=res
    })

    let userReadNumIsOverThree=false
    //获取每个用户的阅读图书列表
    for(var i=0;i<userList.length;i++){
      let userinfo={}
      await getUserReadList(userList[i].username).then((res)=>{
        userinfo.username=userList[i].username
        userinfo.bookList=JSON.parse(JSON.stringify(res));  
        if(userinfo.username===req.body.username&&userinfo.bookList.length>=3){
          userReadNumIsOverThree=true
        }
        userReadList.push(userinfo)
      })
    }
    if(userReadNumIsOverThree){
      try{
        let usersub
        //获取相似度矩阵
        for(var i=0;i<userReadList.length;i++){
          //记录目标用户的下标
          if(userReadList[i].username===req.body.username){
            usersub=i
          }
          similarityMatrix[i]=[]
          for(var j=0;j<userReadList.length;j++){
            if(i===j){
              //自己与自己的相似度一定为1，为了后续方便过滤出除自己以外的用户，将相似度设为-1
              similarityMatrix[i][j]=-1
            }
            else if(!userReadList[i].bookList||!userReadList[j].bookList){
              //用户没有阅读过书籍，相似度为0
              similarityMatrix[i][j]=0
            }
            else{
              var sameBook=[...userReadList[i].bookList].filter(x => [...userReadList[j].bookList].some(y => y.bookname === x.bookname))
              similarityMatrix[i][j]=sameBook.length/Math.sqrt(userReadList[i].bookList.length*userReadList[j].bookList.length)
            }
          }
        }
        var max = 0;
        var secmax = 0;
        var sub = 0;
        var secsub = 0;
        var thmax = 0;
        var thsub = 0;
        //获取与目标用户相似度前三的用户
        for(var i=0;i<userReadList.length;i++){
          if (similarityMatrix[usersub][i] > max) {
            max = similarityMatrix[usersub][i];
            sub = i;
          } else if (similarityMatrix[usersub][i] > secmax) {
            secmax = similarityMatrix[usersub][i];
            secsub = i;
          } else if (similarityMatrix[usersub][i] > thmax){
            thmax = similarityMatrix[usersub][i];
            thsub = i;
          }
        }
        //去除目标用户读过读书
        maxdifflist= [...userReadList[sub].bookList].filter(x => [...userReadList[usersub].bookList].every(y => y.bookname !== x.bookname));
        secdifflist=[...userReadList[secsub].bookList].filter(x => [...userReadList[usersub].bookList].every(y => y.bookname !== x.bookname));
        thdifflist=[...userReadList[thsub].bookList].filter(x => [...userReadList[usersub].bookList].every(y => y.bookname !== x.bookname));
        alldifflist=[...maxdifflist,...secdifflist,...thdifflist]
        alldifflist=new Set(alldifflist)
        let userReadBookTitle=[]
        for(var i=0;i<3;i++){
          await getBookInfo(userReadList[usersub].bookList[i].bookname).then((res)=>{
            userReadBookTitle.push(res[0].title)
          })
        }
        for(var e of alldifflist){
          await getBookInfo(e.bookname).then((res)=>{
            guessYouLike.push(getGuessYouLike(handleData(JSON.parse(JSON.stringify(res[0]))),userReadBookTitle))
          })
        }
        if(guessYouLike.length<9){
          randomArray(9-guessYouLike.length,length).forEach(key=>{
            guessYouLike.push(createGuessYouLike(createData(results,key)))
          })
        }
      }catch(err){
        console.log(err)
      }
    }else{
      randomArray(9,length).forEach(key=>{
        guessYouLike.push(createGuessYouLike(createData(results,key)))
      })
    }
    
    
    
    
    for(var i=0;i<length;i++){
      //获取每本书的阅读人数
      await getAllBookReader(results[i]).then((res)=>{
        readbook.push(res)
      })
    }
    //获取前三的热门阅读
    await getThrReader(readbook).then(async (res)=>{
      recommend.push(createData(readbook,res.firsub))
      recommend.push(createData(readbook,res.secsub))
      recommend.push(createData(readbook,res.thrsub))
    })

    randomArray(6,length).forEach(key=>{
      featured.push(createData(results,key))
    })
    randomArray(1,length).forEach(key=>{
      random.push(createData(results,key))
    })
    res.json({
      guessYouLike,
      banner,
      recommend,
      featured,
      random,
      categoryList,
      categories
    })
  })
}

exports.getBookDetail=(req,res)=>{
  const fileName=req.query.fileName
  // 防止sql注入，自动对问号内容进行参数编码
  const sql='select * from book where fileName= ?'
  conn.query(sql,fileName,(err,results)=>{
    if(err){
      res.json({
        error_code:1,
        msg:'电子书详情获取失败'
      })
    }else{
      if(results&&results.length===0){
        res.json({
          error_code:1,
          msg:'电子书详情获取失败'
        })
      }else{
        const book=handleData(results[0])
        res.json({
          error_code:0,
          msg:'电子书获取成功',
          data:book
        })
      }
    }
  })
}

exports.getBookList=(req,res)=>{
  conn.query('select * from book where cover!=\'\'',(err,results)=>{
    if(err){
      res.json({
        error_code:1,
        msg:'数据库失败'
      })
    }
    else{
      results.map(item=>handleData(item))
      const data={}
      constant.category.forEach(categoryText=>{
        data[categoryText]=results.filter(item=>item.categoryText===categoryText)
      })
      res.json({
        error_code:0,
        msg:'获取成功',
        data:data,
        total:results.length
      })
    }
  })
}

exports.getFlatList=(req,res)=>{
  conn.query('select * from book where cover!=\'\'',(err,results)=>{
    if(err){
      res.json({
        error_code:1,
        msg:'数据库失败'
      })
    }
    else{
      results.map(item=>handleData(item))
      res.json({
        error_code:0,
        msg:'获取成功',
        data:results,
        total:results.length
      })
    }
  })
}